import { _decorator, Asset, assetManager, Button, Component, director, EditBox, error, find, ImageAsset, instantiate, Label, Node, PageView, Prefab, ProgressBar, resources, RichText, Script, ScrollView, Skeleton, Slider, sp, Sprite, SpriteAtlas, SpriteFrame, Texture2D, Toggle, tween } from "cc";
import BaseUISelf from '../framwork/BaseUI';
import AudioTools from "./Tools/AudioTools";

const { ccclass, property } = _decorator;
export interface CreateUIObj{
	id:number;
	prefabUrl:string;
	View:Node;
	data:any;
}

@ccclass('Game')
export default abstract class BaseUI extends Component {
    private createUIDongHua = "左入";   //创建界面动画
    private closeUIDongHua = "右出";    //关闭界面动画
    private prefabPath = "prefab";      //prefab路径
    private audioPath = "audio";        //音频路径

    abstract data;
    abstract BaseUIonLoad(): void;
    abstract BaseUIonDestroy(): void;
    abstract onBtn_click(target: Button, onBtn_name: string): number | void;
    protected onLoad(): void {
        this.autoButtonEvent();
        this.BaseUIonLoad();
    }
    //自动注册所有button点击事件
    autoButtonEvent(){
        let btns = this.node.getComponentsInChildren(Button);
        btns.forEach(element => {
            element.node.on(Button.EventType.CLICK,()=>{
                this._onBtnClicked(element);
            },this);
        });
    }
    _onBtnClicked(btn:Button) {
        let dt = this.onBtn_click(btn,btn.node.name) || 0.2;
        btn.enabled = false;
        if(dt >= 0){
            this.scheduleOnce(() => { btn.enabled = true }, dt);
        }
        //==========================点击音效
        console.log(btn);
        AudioTools.clickAudio();
    }
    //预加载所有prefab
    loadAllPrefab(proBar:ProgressBar = null, prefab:string = this.prefabPath){
        return new Promise((resolve, reject) => {
            let tw = null;  
            if(proBar){
                proBar.progress = 0;
                tw = tween(proBar).to(10, { progress: 1 }, { easing: 'linear' }).start();
            }
            resources.loadDir(prefab, Prefab, (err, res) => {
                if (err) {
                    console.error("BaseUI_loadAllPrefab 文件夹中没有找到prefab文件：",err,prefab);
                    reject(err);
                }
                if(proBar){
                    tw.stop()
                    tween(proBar).to(0.4, { progress: 1 }, { easing: 'linear' }).start();
                    this.scheduleOnce(()=>{ resolve(res); },0.5)
                } else {
                    resolve(res);
                }
            });
        });
    }

    //Start 创建 关闭 UI ======================================================================
    createUI(path:string, parentNode:Node,data):Promise<any>{
    return new Promise((resolve, reject) => {
        let parent = find("Canvas");
        if(parentNode){ parent = parentNode; }
        let prefabs = resources.getDirWithPath(this.prefabPath);
        console.log(prefabs);
        //过滤包含path字符 且是结尾的路径
        let filePaths = [];
        for (let index = 0; index < prefabs.length; index++) {
            let tempSplit = prefabs[index].path.split(path);
            if(tempSplit.length == 2 && tempSplit[1] == ""){
                filePaths.push(prefabs[index].path);
            }
        }
        if(filePaths.length <= 0){
            console.error("BaseUI_createUI 没有找到prefab文件：",path);
            resolve(null);
        } else if(filePaths.length > 1){    
            console.error("BaseUI_createUI 找到多个prefab文件：",filePaths);
            resolve(null);
        } else {
            this.loadResources(filePaths[0], Prefab).then((ret:Prefab)=>{
                let node:Node = instantiate(ret);
                let components = node.getComponents(Component);
                let baseUIs:BaseUI[] = components.filter(component => component instanceof BaseUI);
                for (let index = 0; index < baseUIs.length; index++) {
                    baseUIs[index].data = data;
                }
                parent.addChild(node);
                resolve(ret);
            });
        }
    })}
    private loadResources(path: string, type: typeof Asset): Promise<Asset|Prefab> {
        return new Promise((resolve, reject) => {
            resources.load(path, type, (err, ret) => {
                if (err) {
                    console.error("BaseUI_loadResources 加载 本地 资源出错:", path, err);
                    reject(err);
                } else {
                    resolve(ret);
                }
            })
        })
    }

    closeUI(fun:Function = null) {
        if (this.node) {
            fun && fun();
            this.node.active = false;
            this.node.parent = null;
            this.node.removeFromParent();
        }
    }
    static queueUI:CreateUIObj[] = [] // 创建窗口队列
    static queueUIId = 0;             // 创建窗口队列id
    static nowShowQueueUIId = null;          // 正在显示的窗口id

    /**
     * 设置窗口队列 没有直接显示 有的就放入队列
     * @param that  //创建窗口节点对象
     * @param url   //prefab路径
     * @param view  //创建窗口所在节点
     * @param data  //创建窗口数据
     */
    static setCreateUIQueue(that,url:string,view:Node,data = null){
        let obj = {
            id:this.queueUIId++,
            prefabUrl:url,
            View:view,
            data:data
        }
        if(this.queueUI.length > 0){
            this.queueUI.push(obj);
        } else {
            this.queueUI.push(obj);
            this.showQueueUI(obj,that);
        }
    }

    /**
     * 显示队列中的窗口
     * @param obj   //创建窗口对象
     * @param that  //创建窗口节点对象 
     */
    static showQueueUI(obj:CreateUIObj,that:BaseUI){
        this.nowShowQueueUIId = obj.id;
        that.createUI(obj.prefabUrl,obj.View,obj.data);
    }

    /**
     * 关闭窗口并开启队列中下一个窗口
     * @param that //创建窗口节点对象
     */
    static closeQueueUI(that){
        this.queueUI = this.queueUI.filter(item=>item.id != this.nowShowQueueUIId);
        this.nowShowQueueUIId = null;
        if(this.queueUI[0]){
            this.showQueueUI(this.queueUI[0],that);
        }
    }
    
    //Start 创建 关闭 UI ======================================================================


    //Start获取节点组件================================================================
    // 递归通过名子获取节点
    private _getNodeByName(fnode:Node,name:string):Node{
        let node:Node = fnode.getChildByName(name);
        if(node){ return node; }
        if(fnode.children.length <= 0){ return null; }
        for (let index = 0; index < fnode.children.length; index++) {
            let tempNode:Node = this._getNodeByName(fnode.children[index],name);
            if(tempNode){ return tempNode; }
        }
    }
    public GetGameObject(name:string):Node{
        return this.GetNodeByName(name);
    }
    // 通过名子获取节点
    public GetNodeByName(name:string):Node{
        return this._getNodeByName(this.node,name);
    }
    // 通过名子 从最上层节点开始获取节点
    public GetParentsNodeByName(name):Node{
        let nownode = this.node;
        while (nownode.parent) {
            nownode = nownode.parent;
        } ;
        return this._getNodeByName(nownode,name);
    }
    GetSkeleton(node: Node|string):sp.Skeleton {
        if(node instanceof Node){
            return node.getComponent(sp.Skeleton)
        } else{
            let sNode = this.GetNodeByName(node)
            if(sNode){
                return sNode.getComponent(sp.Skeleton);
            } else {
                console.error("BaseUI_GetSkeleton 没有找到节点："+node);
                return null
            }
        }
    }
    //获取文字框组件
    GetLable(node:Node|string):Label{
        if(node instanceof Node){
            return node.getComponent(Label)
        } else{
            let sNode = this.GetNodeByName(node)
            if(sNode){
                return sNode.getComponent(Label);
            } else {
                console.error("BaseUI_GetLable 没有找到节点："+node);
                return null
            }
        }
    }
    //设置文字框组件 
    SetLable(node:Node|string,str:string){
        if(node instanceof Node){
            node.getComponent(Label).string = str;
        } else{
            let sNode = this.GetNodeByName(node)
            if(sNode){
                sNode.getComponent(Label).string = str;
            } else {
                console.error("BaseUI_SetLable 没有找到节点："+node);
            }
            
        }
    }
    SetParentsLable(node:Node|string,str:string){
        if(node instanceof Node){
            node.getComponent(Label).string = str;
        } else{
            let sNode = this.GetParentsNodeByName(node);
            if(sNode){
                sNode.getComponent(Label).string = str;
            } else {
                console.error("BaseUI_SetParentsLable 没有找到节点："+node);
            }
            
        }
    }
    GetRichText(node:Node|string): RichText {
        if(node instanceof Node){
            return node.getComponent(RichText)
        } else{
            let sNode = this.GetNodeByName(node)
            if(sNode){
                return sNode.getComponent(RichText);
            } else {
                console.error("BaseUI_GetRichText 没有找到节点："+node);
                return null
            }
        }
    }
    SetRichText(node:Node|string,str:string){
        if(node instanceof Node){
            node.getComponent(RichText).string = str;
        } else{
            let sNode = this.GetNodeByName(node)
            if(sNode){
                sNode.getComponent(RichText).string = str;
            } else {
                console.error("BaseUI_SetRichText 没有找到节点："+node);
            }
        }
    }
    GetSprite(node: string | Node){
        if (node instanceof Node) {
            return node.getComponent(Sprite);
        } else{
            let sNode = this.GetNodeByName(node)
            if(sNode){
                return sNode.getComponent(Sprite);
            } else {
                console.error("BaseUI_GetSprite 没有找到节点："+node);
            }
        }
    }
    //设置图片组件
    SetSprite(node: string | Node, filepath: string): Promise<SpriteFrame> {
    return new Promise((resolve, reject) => {
        let sprite: Sprite = this.GetSprite(node);
        if (sprite) {
            resources.load(filepath+'/spriteFrame', Asset, (err, spriteFrame:SpriteFrame) => {
                if (err) {
                    console.error("BaseUI_SetSprite 没有找到spriteFrame："+ filepath);
                    return;
                }
                sprite.spriteFrame = spriteFrame;
            });
        }
    })}

    //等有图集再弄
    // SetAtlasSprite(node: string | Node, filepath: string, image: string): Promise<cc.SpriteFrame> {
    // return new Promise((resolve, reject) => {
    //     let sprite: Sprite = this.getSprite(node);
    //     if (sprite) {
    //         resources.load(filepath+'/spriteFrame', Asset, (err, spriteFrame:SpriteFrame) => {
    //             if (err) {
    //                 console.error("BaseUI_getSprite 没有找到spriteFrame："+ filepath);
    //                 return;
    //             }
    //             sprite.spriteFrame = spriteFrame;
    //         });
    //     }
    // })
    // }
    SetUrlSprite(node: string | Node, filepath: string): Promise<SpriteFrame> {
    return new Promise((resolve, reject) => {
        let sprite: Sprite = this.GetSprite(node);
        if (sprite) {
            assetManager.loadRemote<Texture2D>(filepath, (err, texture:ImageAsset) => {
                if (err) {
                    console.error("BaseUI_SetUrlSprite 没有找图片："+ filepath);
                    return;
                }
                const spriteFrame = new SpriteFrame();
                const texture2d = new Texture2D();
                texture2d.reset({
                    width: texture.width,
                    height: texture.height,
                    format: Texture2D.PixelFormat.RGBA8888, // 根据图片格式调整
                });
                texture2d.uploadData(texture.data)
                spriteFrame.texture = texture2d;
                sprite.spriteFrame = spriteFrame;
            });
        }
    })}
    GetProgressBar (node:Node|string): ProgressBar {
        if(node instanceof Node){
            return node.getComponent(ProgressBar)
        } else{
            let sNode = this.GetNodeByName(node)
            if(sNode){
                return sNode.getComponent(ProgressBar);
            } else {
                console.error("BaseUI_GetProgressBar 没有找到节点："+node);
                return null
            }
        }
    }
    SetProgressBar(node:Node|string,num:number){
        if(num>1){
            num = 1;
            console.error("BaseUI_SetProgressBar 进度条取值范围是0~1："+node);
        }
        if(num<0){
            num = 0;
            console.error("BaseUI_SetProgressBar 进度条取值范围是0~1："+node);
        }  
        if(node instanceof Node){
            node.getComponent(ProgressBar).progress = num;
        } else{
            let sNode = this.GetNodeByName(node)
            if(sNode){
                sNode.getComponent(ProgressBar).progress = num;
            } else {
                console.error("BaseUI_SetProgressBar 没有找到节点："+node);
            }
        }
    }
    GetButton(node:Node|string): Button {
        if(node instanceof Node){
            return node.getComponent(Button)
        } else{
            let sNode = this.GetNodeByName(node)
            if(sNode){
                return sNode.getComponent(Button);
            } else {
                console.error("BaseUI_GetButton 没有找到节点："+node);
                return null
            }
        }
    }
    GetEditBox(node:Node|string): EditBox {
        if(node instanceof Node){
            return node.getComponent(EditBox)
        } else{
            let sNode = this.GetNodeByName(node)
            if(sNode){
                return sNode.getComponent(EditBox);
            } else {
                console.error("BaseUI_GetEditBox 没有找到节点："+node);
                return null
            }
        }
    }
    SetEditBox(node:Node|string,str:string){
        if(node instanceof Node){
            node.getComponent(EditBox).string = str;
        } else{
            let sNode = this.GetNodeByName(node)
            if(sNode){
                sNode.getComponent(EditBox).string = str;
            } else {
                console.error("BaseUI_SetEditBox 没有找到节点："+node);
            }
        }
    }

    GetSlider(node:Node|string): Slider {
        if(node instanceof Node){
            return node.getComponent(Slider)
        } else{
            let sNode = this.GetNodeByName(node)
            if(sNode){
                return sNode.getComponent(Slider);
            } else {
                console.error("BaseUI_GetSlider 没有找到节点："+node);
                return null
            }
        }
    }
    SetSlider(node:Node|string,num:number){
        if(num>1){
            num = 1;
            console.error("BaseUI_SetSlider 进度条取值范围是0~1："+node);
        }
        if(num<0){
            num = 0;
            console.error("BaseUI_SetSlider 进度条取值范围是0~1："+node);
        }  
        if(node instanceof Node){
            node.getComponent(Slider).progress = num;
        } else{
            let sNode = this.GetNodeByName(node)
            if(sNode){
                sNode.getComponent(Slider).progress = num;
            } else {
                console.error("BaseUI_SetSlider 没有找到节点："+node);
            }
        }
    }
    GetScrollView(node:Node|string): ScrollView {
        if(node instanceof Node){
            return node.getComponent(ScrollView)
        } else{
            let sNode = this.GetNodeByName(node)
            if(sNode){
                return sNode.getComponent(ScrollView);
            } else {
                console.error("BaseUI_GetScrollView 没有找到节点："+node);
                return null
            }
        }
    }

    GetToggle(node:Node|string): Toggle {
        if(node instanceof Node){
            return node.getComponent(Toggle)
        } else{
            let sNode = this.GetNodeByName(node)
            if(sNode){
                return sNode.getComponent(Toggle);
            } else {
                console.error("BaseUI_GetToggle 没有找到节点："+node);
                return null
            }
        }
    }
    GetPageView(node:Node|string): PageView {
        if(node instanceof Node){
            return node.getComponent(PageView)
        } else{
            let sNode = this.GetNodeByName(node)
            if(sNode){
                return sNode.getComponent(PageView);
            } else {
                console.error("BaseUI_GetPageView 没有找到节点："+node);
                return null
            }
        }
    }
    SetPageView(node: string|Node, page: number) {
        page = Math.floor(page);
        if(node instanceof Node){
            if(page > node.getComponent(PageView).getPages.length -1){
                console.error("BaseUI_SetPageView 页面超出范围："+node);
            } else {
                node.getComponent(PageView).setCurrentPageIndex(page);
            }
            
        } else{
            let sNode = this.GetNodeByName(node)
            if(sNode){
                if(page > sNode.getComponent(PageView).getPages.length -1){
                    console.error("BaseUI_SetPageView 页面超出范围："+node);
                } else {
                    sNode.getComponent(PageView).setCurrentPageIndex(page);
                }
            } else {
                console.error("BaseUI_SetPageView 没有找到节点："+node);
            }
        }
    }
    //End获取节点组件================================================================
}
